package frontend.components.form;

import frontend.model.base.UIModel;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.Localizer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.validation.ValidationError;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public abstract class ValidatableForm<UIM extends UIModel> extends Form<UIM> {
    private static final String RESOURCE_KEY_VALIDATION_FIELD_NOT_EMPTY_OR_NULL = "validation.form.generic.notEmpty";
    private static final String RESOURCE_KEY_VALIDATION_FIELD_NOT_EMPTY_SELECTION_OR_NULL = "validation.form.generic.notEmptySelection";
    private static final String RESOURCE_KEY_VALIDATION_FIELD_NOT_NUMERIC = "validation.form.generic.notNumeric";
    private static final String RESOURCE_KEY_VALIDATION_GENERAL_PREFIX = "validation.general.prefix";

    protected UIM uiModel;
    protected List<ValidationError> validationErrors;
    protected FeedbackPanel feedbackPanel;

    public ValidatableForm(String id, UIM uiModel) {
        super(id, new CompoundPropertyModel<UIM>(uiModel));

        validationErrors = new ArrayList<ValidationError>();
        this.uiModel = uiModel;

        constructFormContent();
        constructFeedbackPanel();
    }

    protected abstract void constructFormContent();

    private void constructFeedbackPanel() {
        feedbackPanel = new FeedbackPanel("feedback");
        feedbackPanel.setOutputMarkupId(true);
        add(feedbackPanel);
    }

    protected abstract void doFormValidation();

    protected void addGeneralValidationError(String validationResourceKey) {
        ValidationError error = createGeneralValidationError(validationResourceKey);
        validationErrors.add(error);
    }

    protected ValidationError createGeneralValidationError(String validationResourceKey) {
        String validationText = Localizer.get().getString(validationResourceKey, null);
        String generalPrefix = Localizer.get().getString(RESOURCE_KEY_VALIDATION_GENERAL_PREFIX, null);
        ValidationError error = new ValidationError();
        error.setMessage(generalPrefix + ": " + validationText);
        return error;
    }

    protected void addValidationError(String validationResourceKey) {
        ValidationError error = createValidationError(validationResourceKey);
        validationErrors.add(error);
    }

    protected ValidationError createValidationError(String validationResourceKey) {
        String validationText = Localizer.get().getString(validationResourceKey, null);
        ValidationError error = new ValidationError();
        error.setMessage(validationText);
        return error;
    }

    protected void addFieldValidationError(String fieldResourceKey, String validationResourceKey) {
        String fieldName = Localizer.get().getString(fieldResourceKey, null);
        String validationText = Localizer.get().getString(validationResourceKey, null);
        ValidationError error = new ValidationError();
        error.setMessage(fieldName + ": " + validationText);
        validationErrors.add(error);
    }

    protected void addFieldValidationErrorForAlreadyLocalizedMessage(String fieldResourceKey, String localizedMessage) {
        String fieldName = Localizer.get().getString(fieldResourceKey, null);
        ValidationError error = new ValidationError();
        error.setMessage(fieldName + ": " + localizedMessage);
        validationErrors.add(error);
    }


    protected boolean validateNotEmpty(Object fieldValue, String fieldResourceKey) {
        if (fieldValue == null || StringUtils.isEmpty(fieldValue.toString())) {
            addFieldValidationError(fieldResourceKey, RESOURCE_KEY_VALIDATION_FIELD_NOT_EMPTY_OR_NULL);
            return false;
        }
        return true;
    }

    protected boolean validateIsNumeric(String fieldValue, String fieldResourceKey) {
        try {
            if (fieldValue != null) {
                Long.parseLong(fieldValue);
                return true;
            }
        }
        catch (NumberFormatException ex) {
            addFieldValidationError(fieldResourceKey, RESOURCE_KEY_VALIDATION_FIELD_NOT_NUMERIC);
        }
        return false;
    }

    protected boolean validateNotEmptySelection(Collection fieldValue, String fieldResourceKey) {
        if (fieldValue == null || fieldValue.isEmpty()) {
            addFieldValidationError(fieldResourceKey, RESOURCE_KEY_VALIDATION_FIELD_NOT_EMPTY_SELECTION_OR_NULL);
            return false;
        }
        return true;
    }
}